package de.fuberlin.inf.alp2;

public class CLList {
	private Node anchor;
	
	public CLList(){
		this.anchor = new Node();
		this.anchor.setNext(this.anchor);
	}
	
	public Object getFirst(){
		return this.anchor.getValue();
	}
	
	public Object get(int index){
		return this.getNode(index).getValue();
	}
	
	public Node getNode(int index){
		Node current = this.anchor;
		for (int i = 0; i < index; i++)
			current = current.getNext();
		return current;
	}
	
	public Node getNextRing(Node current){
		if (isEmpty())
			return null; // empty list
		if (current.getNext() == this.anchor)
			return this.anchor.getNext();
		return current.getNext();
	}
	
	public int size(){
		int returnValue = 0;
		Node current = this.anchor.getNext();
		while (current != this.anchor){
			returnValue++;
			current = current.getNext();
		}
		return returnValue;
	}
	
	public void addFirst(Object obj){
		anchor.setNext(new Node(obj, this.anchor.getNext()));
	}
	
	public void clear(){
		this.anchor.setNext(this.anchor);
	}
	
	public boolean isEmpty(){
		return this.anchor.getNext() == this.anchor;
	}
	
	public boolean contains (Object obj){
		Node current = this.anchor.getNext();
		if (current == null)
			return false;
		while (current != anchor){
			if (current.getValue().equals(obj))
				return true;
			current = current.getNext();
		}
		return false;
	}
	
	public void remove(Node node){
		Node current = this.anchor.getNext();
		Node previous = this.anchor;
		while (current != this.anchor){
			if (current == node){
				previous.setNext(current.getNext());
				break;
			}
			else
				previous = current;
			current = current.getNext();
		}
	}
	
	public void remove(Object obj){
		Node current = this.anchor.getNext();
		Node previous = this.anchor;
		while (current != this.anchor){
			if (current.getValue().equals(obj))
				previous.setNext(current.getNext());
			else
				previous = current;
			current = current.getNext();
		}
	}
	
	public String toString(){
		if (isEmpty())
			return "List is empty";
		StringBuffer returnValue = new StringBuffer();
		returnValue.append("The List:\n");
		Node current = this.anchor.getNext();
		while (current.getNext() != this.anchor){
			returnValue.append(current.getValue() + ", ");
			current = current.getNext();
		}
		returnValue.append(current.getValue() + "\n");
		return returnValue.toString();
	}
	
	public void reverseRek(){
		Node firstWillBeLast = this.anchor.getNext();
		this.reverseRek(firstWillBeLast);
		firstWillBeLast.setNext(this.anchor);
	}
	private Node reverseRek(Node node){
		if (node == this.anchor)
			return this.anchor;
		if (node.getNext() == this.anchor){
			this.anchor.setNext(node);
			return node;
		}
		reverseRek(node.getNext()).setNext(node);
		return node;
	}
	     
	public void reverseIt(){
		Node current = this.anchor.getNext();
		Node previous = this.anchor;
		while (current != this.anchor){
			Node next = current.getNext();
			current.setNext(previous);
			previous = current;
			current = next;
		}
		this.anchor.setNext(previous);
	}

}
